home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / e / kyz_obj.lha / doc / patch.doc < prev    next >
Text File  |  1998-10-18  |  16KB  |  399 lines

  1. TABLE OF CONTENTS
  2.  
  3. patch.m/--overview--
  4. patch.m/disable
  5. patch.m/enable
  6. patch.m/end
  7. patch.m/install
  8. patch.m/missed
  9. patch.m/patched_function
  10. patch.m/remove
  11. patch.m/--overview--                                     patch.m/--overview--
  12.  
  13.    PURPOSE
  14.     To allow easy patching of Amiga library and device functions
  15.     with Amiga E code.
  16.  
  17.    OVERVIEW
  18.     The AmigaOS has a facility to change the code called in any of the
  19.     functions  of  a  library  or  device.  But due to the way Amiga E
  20.     works, it has been difficult to easily use E code as patches.
  21.  
  22.     This  object  allows  you  to  perform patches on the system using
  23.     Amiga E code in the most flexible way, via an assembler wedge.
  24.  
  25.     Installation:
  26.  
  27.     You  first  need  to open the library/device that you are going to
  28.     patch.  You  then  need  to  know the Library Vector Offset of the
  29.     entry  you  are  going to patch. This is available using the 'lvo'
  30.     tool  from  the  Developer Kit, or any assembler include file with
  31.     'LVO'  in the title. You must keep the library/device open for the
  32.     entire  duration  of  the patch. If you do not, the library may be
  33.     flushed from memory and loaded somewhere else, indirectly removing
  34.     the  patch  and  also  causing  a  crash when we try to remove our
  35.     defunct patch later.
  36.  
  37.     You  create  a patch object with install(), which installs a wedge
  38.     that calls an E function which you defined like so:
  39.  
  40.         PROC patch_code(function, a7,a6,a5,a4,a3,a2,a1,a0,
  41.                                   d7,d6,d5,d4,d3,d2,d1,d0)
  42.  
  43.     You  can give alternate names to the 'register' parameters, but do
  44.     remember  that  they  will  always  be  passed IN THE ABOVE-STATED
  45.     ORDER, and writing the parameter's names in a different order will
  46.     NOT cause the registers to be passed to you in a different order.
  47.  
  48.     See patched_function() for more about this.
  49.  
  50.     Your patch in operation:
  51.  
  52.     This  E  function is called 'as' the function you have patched, by
  53.     absolutely  any  task  and  program  that  could call the original
  54.     function.  Also,  the  function  may  be  called  by more than one
  55.     program  at  once,  so  use a Semaphore or similar protection when
  56.     using global variables.
  57.  
  58.     You are given all the registers as set when the patch was called -
  59.     do  NOT modify them unless it is documented that the function does
  60.     this.  That said, you can always modify the 'd0' variable as it is
  61.     ignored  on exit, the return value of your function is returned in
  62.     D0 rather than the stack-based copy.
  63.  
  64.     Occasionally  you  can modify the 'scratch register' variables d0,
  65.     d1,  a0  and  a1,  but  you  must  check  the documentation of the
  66.     function  you  are  patching,  to  ensure  it  does not promise to
  67.     preserve any of these registers.
  68.  
  69.     The result of your function call is always returned in D0, but E's
  70.     multiple return values (in D1 and D2) are ignored, and restored to
  71.     their original values.
  72.  
  73.     Calling the original function:
  74.  
  75.     You  are  also  given  a pointer to the original function you have
  76.     patched.  In  most  patches,  you  will  have to call the original
  77.     function sometime, so you would set up the registers appropriately
  78.     from  the parameters, including A6 as the library/device base, and
  79.     call  the  original  function.  Do  NOT  do  this by writing the E
  80.     construct "function()", as this will use an unspecified A-register
  81.     to  make  the  call. Instead, do it yourself with another register
  82.     that  you choose. If you need to pass A0 to A3 as parameters, then
  83.     you will have to preserve and use A4 or A5.
  84.  
  85.     Patch removal:
  86.  
  87.     Your  patch  can be either enabled or disabled. When disabled, the
  88.     assembler  wedge  simply  hops  to  the  original function, adding
  89.     nothing  to  the  stack. Simply exiting your program at this point
  90.     without  ENDing  the  object would free the object instance itself
  91.     but would leave the working wedge in place, consuming 136 bytes of
  92.     memory and adding 3 instructions to the function.
  93.  
  94.     Some  people  would  advocate  exiting your program with the wedge
  95.     still in place, as the user is unlikely to do that often, but when
  96.     they do there will be no problem with exiting correctly.
  97.  
  98.     Others  would always recommend total removal of the patch, even if
  99.     that  means  waiting. Unlike other wedges, the removal method used
  100.     by  this  object is very safe, only removes the patch if it is not
  101.     being  used,  and understands programs like SetFunction Manager or
  102.     SaferPatches which allow removal of patches in any order.
  103.  
  104.     My  advice  is to always disable() the patch, then try to remove()
  105.     the  patch. If that fails, ask the user if you should keep trying,
  106.     or just exit.
  107.  
  108.    NOTES
  109.     You  must NOT use Amiga E's 'debug' mode and EDBG on the code that
  110.     contains  the  patch you will be making. E introduces NOP commands
  111.     into  the  code,  which  EDBG turns to ILLEGAL commands, so it can
  112.     run the E code in the normal way, then give control back to itself
  113.     after  each  line.  However,  when  the  E code is called by other
  114.     tasks,  these  ILLEGALs  are not trapped by EDBG, and simply crash
  115.     the  task  involved.  A  simple  fix is to put the patch code in a
  116.     seperate module, and compile this without debug mode.
  117.  
  118.     Exceptions  should never be thrown out of patches. If there is the
  119.     possibility  of an exception being raised, make the patch function
  120.     HANDLE it, not throw it out.
  121.  
  122.     Some functions are marked as safe to be called from interrupts. If
  123.     this  is  the  case, you have to handle the possible deadlock that
  124.     may  occur  -  interrupt blocks a task, then goes into a loop that
  125.     waits for the blocked task to finish, which it will never do.
  126.  
  127.     If  the function you are patching is part of the AmigaOS, remember
  128.     to check the function's autodocs for defined side effects that you
  129.     must emulate.
  130.  
  131.     You  obviously  cannot  call  the function you patched through the
  132.     usual way, but you also cannot call a system/library function that
  133.     calls your patched function as part of its operation.
  134.  
  135.     You cannot perform I/O on _your_ streams from another process, and
  136.     tasks  can't  even  call any DOS functions. Therefore, WriteF() in
  137.     your patch is out of the question. Use debug.m/kPrintF and Sushi.
  138.  
  139.    WARNING
  140.     When your patch is enabled, the combination of assembler wedge and
  141.     E code will add a MINIMUM of 80 bytes - THEN extra bytes are added
  142.     for the variables in your patch!
  143.  
  144.     You should minimise local variable usage - even register variables
  145.     add to stack usage - and avoid defining entire structures, STRINGs
  146.     or LISTs as local variables.
  147.  
  148. patch.m/disable                                               patch.m/disable
  149.  
  150.    NAME
  151.     patch.disable() -- prevent further execution of the patch.
  152.  
  153.    SYNOPSIS
  154.     disable()
  155.  
  156.    FUNCTION
  157.     Stops the patch from being invoked again. All calls to the patched
  158.     function  will be passed directly to the original function, not to
  159.     your patch.
  160.  
  161.     There  may,  however, still be invocations of the patch running at
  162.     the time this call returns.
  163.  
  164.    SEE ALSO
  165.     enable()
  166.  
  167. patch.m/enable                                                 patch.m/enable
  168.  
  169.    NAME
  170.     patch.enable() -- allow execution of the patch.
  171.  
  172.    SYNOPSIS
  173.     enable()
  174.  
  175.    FUNCTION
  176.     Toggles a switch in the assembler wedge which stops it passing all
  177.     calls of the patched function to the original function, and starts
  178.     passing them to your patch.
  179.  
  180.     Your  patch  should  be ready to run at any time from the start of
  181.     the call to this method.
  182.  
  183.    SEE ALSO
  184.     disable()
  185.  
  186. patch.m/end                                                       patch.m/end
  187.  
  188.    NAME
  189.     patch.end() -- Destructor.
  190.  
  191.    SYNOPSIS
  192.     end()
  193.  
  194.    FUNCTION
  195.     Frees  resources  used  by an instance of the patch class. It will
  196.     first  disable() the patch, then it will busy loop until the patch
  197.     is successfully removed.
  198.  
  199.    SEE ALSO
  200.     disable(), remove(), install()
  201.  
  202. patch.m/install                                               patch.m/install
  203.  
  204.    NAME
  205.     patch.install() -- Constructor.
  206.  
  207.    SYNOPSIS
  208.     install(base, offset, patchfunc)
  209.     install(base, offset, patchfunc, userdata)
  210.     install(base, offset, patchfunc, userdata, stackuse)
  211.  
  212.    FUNCTION
  213.     Initialises  an  instance of the patch class, and installs a patch
  214.     in the system. The patch will not be enabled to begin with, so you
  215.     must  call  enable()  on  the  patch  for it to start working. The
  216.     exceptio